from absl import app, flags
import pandas as pd

from coin.support.accounting.logic.format_util import *
from xunkemgmt.support.accounting.logic.query_request import _gen_engine as \
  gen_accounting_engine
from coin.support.exchange_status.logic.db_connector import \
  gen_sqlalchemy_query_engine as gen_exchange_status_engine

from coin.exchange.kr_rest.product.product_impl import generate_product_from_str

FLAGS = flags.FLAGS

MONITOR_LIST = {
    ('Bitflyer', 'Futures', None): {
        'symbol': ['BTC-JPY.PERPETUAL'],
        'host': [
            'exchange-status-01.cn-hongkong.aliyun',
            'exchange_status-02.ap-northeast-1.aws',
            'exchange_status-03.eu-west-1.aws'
        ]
    }, ('Bitmex', 'Futures', None): {
        'symbol': ['BTC-USD.PERPETUAL'],
        'host': [
            'exchange-status-01.cn-hongkong.aliyun',
            'exchange_status-02.ap-northeast-1.aws',
            'exchange_status-03.eu-west-1.aws'
        ]
    }, ('Okex', 'Spot', None): {
        'symbol': ['BTC-USDT'],
        'host': [
            'exchange-status-01.cn-hongkong.aliyun',
            'exchange_status-02.ap-northeast-1.aws',
            'exchange_status-03.eu-west-1.aws'
        ]
    }, ('Okex', 'Futures', 'futures'): {
        'symbol': ['BTC-USD.THIS_WEEK'],
        'host': [
            'exchange-status-01.cn-hongkong.aliyun',
            'exchange_status-02.ap-northeast-1.aws',
            'exchange_status-03.eu-west-1.aws'
        ]
    }
}


def _get_monitor_data():
  monitor_data = []
  for (exchange, market_type, api_version), config in MONITOR_LIST.items():
    for symbol in config['symbol']:
      symbol = generate_product_from_str(exchange, api_version, symbol).symbol
      for host in config['host']:
        monitor_data.append((exchange, market_type, api_version, symbol, host))
  return pd.DataFrame(monitor_data,
                      columns=['exchange', 'market_type', 'api_version', 'symbol', 'hostname'])


def _is_na(val):
  return val is None or pd.isna(val)


def query_and_print(engine, request_data, title, sql_file):
  data2 = pd.read_sql(open(sql_file, 'r').read(), engine)
  data = request_data.merge(data2, how='left', on=['exchange_api_id', 'symbol', 'hostname'])

  time_cols = [
      'time_to_query', 'time_to_received_feed', 'time_to_changed_feed', 'time_to_valid_feed'
  ]
  for column in time_cols:
    data[column] = \
      data[column].apply(lambda x: pretty_time_delta(x.total_seconds())
                         if not _is_na(x) else '__:__:__')
    data[column] = \
      data['exchange_api_id'].map(str).fillna('') + ' | ' + data[column]

  for column in ('api_version', 'hostname', 'feed_name'):
    data[column] = data[column].apply(lambda x: x if not _is_na(x) else '')
  data['feed_valid'] = data['feed_valid'].apply(lambda x: str(bool(x)) if not _is_na(x) else '')

  def aggf(x):
    return ','.join(x.tolist())

  datat = pd.pivot_table(data,
                         index=['exchange', 'market_type', 'api_version', 'symbol', 'hostname'],
                         values=[
                             'feed_name',
                             'feed_valid',
                             'time_to_received_feed',
                             'time_to_changed_feed',
                             'time_to_valid_feed'
                         ],
                         aggfunc=aggf)

  print()
  print(title)
  print(datat.fillna(''))


def get_feed_status():
  accounting_engine = gen_accounting_engine()
  status_engine = gen_exchange_status_engine()
  monitor_data = _get_monitor_data()
  api_data = pd.read_sql('SELECT * FROM ExchangeAPI WHERE active = True', accounting_engine)
  status_req_data = monitor_data.merge(api_data,
                                       how='left',
                                       on=['exchange', 'market_type', 'api_version'])

  query_and_print(status_engine,
                  status_req_data,
                  'feed_status',
                  'coin/support/exchange_status/query_sql/last_feed_status_per_group.sql')


def main(_):
  pd.set_option('display.width', 1000)
  pd.set_option('display.max_rows', None)
  pd.set_option('display.max_columns', None)

  get_feed_status()


if __name__ == '__main__':
  app.run(main)
